package AlgebraLinear.Matriz;

public class MatrizInversa {

	public double[][] calculaInversa(double[][] arg0){
		
		double[][] matriz = FuncoesMatriz.preencherNovaMatriz(arg0);
		FuncoesMatriz.verificaMatrizQuad(matriz);//Para atirar erro no caso de não ser Quadrada
		double[][] inversa = FuncoesMatriz.preencherIdentidade(matriz.length);
		
		//Processo 1
		for(int etapa = 0; etapa < (matriz.length-1); etapa++){
			for(int i = etapa+1; i< matriz.length; i++){
				double mult = -1*(matriz[i][etapa] / matriz[etapa][etapa]);
				matriz[i][etapa] = 0;
				//Atualizo os outros elementos da matriz original
				for(int j = etapa+1; j < matriz[i].length; j++){
					matriz[i][j] = matriz[i][j]+ (mult * matriz[etapa][j]);
				}
				//Atualizo a matriz inversa
				for(int j = 0; j < inversa[i].length; j++){
					inversa[i][j] = inversa[i][j]+ (mult * inversa[etapa][j]);
				}
			}
		}
		
		//Aqui nos temos uma matriz triângular superior, podemos portanto calcular a Determinante
		FuncoesMatriz.verificaDeterminante(matriz);
		
		//Processo 2
		for(int etapa = (matriz.length-1); etapa > 0; etapa--){
			for(int i = etapa-1; i >=0; i--){
				double mult = -1*(matriz[i][etapa] / matriz[etapa][etapa]);
				matriz[i][etapa] = 0;
				
				//Atualizo os outros elementos da matriz original
				for(int j = etapa-1; j >= 0; j--){
					matriz[i][j] = matriz[i][j]+ (mult * matriz[etapa][j]);
				}
				
				//Atualizo a matriz inversa
				for(int j = 0; j < inversa[i].length; j++){
					inversa[i][j] = inversa[i][j]+ (mult * inversa[etapa][j]);
				}
			}
		}
		
		//Faço a divisão final
		for (int i = 0; i < matriz.length; i++) {
			double div = matriz[i][i];
			for (int j = 0; j < inversa.length; j++) {
				inversa[i][j] /=div;
			}
			matriz[i][i] =1;
		}
				
		return inversa;
	}

}
